/*
 * @Author: wwssaabb
 * @Date: 2021-09-03 16:32:40
 * @LastEditTime: 2021-12-13 10:31:13
 * @FilePath: \handwritten-code\main\new.js
 */

/* 
  new做了什么？
    new Promise()=>得到Promise的实例对象
  实例对象和构造函数的关系？
    new Promise(...) instanceof Promise => true
    or 实例对象的隐式原型<===>构造函数的显式原型
  */

function my_new(Func, ...args) {
  //Func必须是一个函数，否则报错
  if (typeof Func !== 'function') {
    throw new TypeError('Type Error')
  }

  //新建一个对象，这个对象的原型指向Func的显式原型
  let instance = Object.create(Func.prototype)

  //执行构造函数，并将this绑定到新建的实例上，得到一个结果res
  const res = Func.apply(instance, args)

  //判断构造函数执行的结果返回指定的类型
  const isObj = typeof res === 'object' && res !== null
  const isFun = typeof res === 'function'

  //如果是引用类型则返回构造函数执行的结果res，反之返回新建的实例对象
  return isObj || isFun ? res : instance
}

function Test(name, age) {
  this.name = name
  this.age = age
  this.say = () => console.log('hello')
}

let p = my_new(Test, '张三', 23)

console.log(p)
console.log(p.say())


// function myNew(fn) {
//   if (typeof fn !== 'function') return new TypeError(`${fn} must be a function`)

//   const obj = Object.create(fn.prototype)
//   const res = fn.apply(obj, Array.prototype.slice.call(arguments, 1))

//   const isObject = typeof res === 'object' && res !== null
//   const isFunction = typeof res === 'function'

//   return isObject || isFunction ? res : obj
// }